﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

// Area.cs
// Contains information about the current Area the player is in (if not the Overworld, 
// so like Cities and Dungeons).  This includes the background image, the npcs, coordinates for 
// returning to the world map, and other things.
namespace RTS_RPG
{
    public class Area
    {
        // Area's Fields
        public String name;
        public GameMap map;
        public List<Vector2> coords; //[0] is the player starting loc, after that they are coords for
        public List<NPC> npcs;             // returning to the world map.
        public List<Site> entries; //For buildings and entries to other areas
        public Site current_site;
        public Vector2 player_location;
        public float player_direction;
        public PlayerStats pstats;

        public IServiceProvider services;
        public Area_TextureManager textures;
        public Area_Loader loader;
        public Boolean active;

        // Constructor
        public Area(String _name, GameMap _map, List<Vector2> _coords,
            PlayerStats _pstats, IServiceProvider _services)
        {
            name = _name;
            map = _map;
            coords = _coords;
            pstats = _pstats;
            player_location = coords[0];
            player_direction = 0.0f;
            current_site = null;

            services = _services;
            active = false;
            textures = null;
            loader = null;
            entries = null;
            npcs = null;
            map = null;
        }

        // returns true if the player has left the area
        public Boolean update(MouseState mstate, KeyboardState kstate)
        {
            if (current_site != null)
            {
                if (current_site.update(mstate, kstate))
                    current_site = null;
                else return false;
            }

            if (active == false)
            {
                active = true;
                textures = new Area_TextureManager(services);
                textures.LoadAreaContent();
                loader = new Area_Loader(name, textures, pstats);
                entries = loader.find_area_entries(services);
                npcs = loader.find_area_npcs();
                map = loader.get_game_map();
            }

            if (player_location.X - (Area_TextureManager.HALF_CHARACTER_SIZE) < 0 ||
                player_location.X + (Area_TextureManager.HALF_CHARACTER_SIZE) > Program.SCREENWIDTH ||
                player_location.Y - (Area_TextureManager.HALF_CHARACTER_SIZE) < 0 ||
                player_location.Y + (Area_TextureManager.HALF_CHARACTER_SIZE) > Program.SCREENHEIGHT)
            {
                player_location = coords[0];
                active = false;
                textures.UnloadAreaContent();
                loader = null;
                entries = null;
                npcs = null;
                map = null;
                return true;
            }

            check_keys(kstate);

            foreach (Site site in entries)
            {
                if (site.check_entry(null, this))
                {
                    current_site = site;
                    active = false;
                    textures.UnloadAreaContent();
                    loader = null;
                    entries = null;
                    npcs = null;
                    map = null;
                }
            }

            if (npcs != null)
            {
                foreach (NPC npc in npcs)
                    npc.update(player_location);
            }

            return false;
        }

        public void draw(SpriteBatch spBatch, GraphicsDevice graphics_dev)
        {
            if (current_site != null)
                current_site.draw_area(spBatch, graphics_dev);

            if (!active) return;

            graphics_dev.Clear(Color.Violet);
            /*spBatch.Draw(pstats.area_representation, new Vector2(
                player_location.X - (Area_TextureManager.HALF_CHARACTER_SIZE),
                player_location.Y - (Area_TextureManager.HALF_CHARACTER_SIZE)),
                Color.White);*/

            if (map != null)
                map.draw(spBatch, graphics_dev);

            spBatch.Draw(pstats.area_representation, player_location, null, Color.White, player_direction,
                new Vector2(Area_TextureManager.HALF_CHARACTER_SIZE, Area_TextureManager.HALF_CHARACTER_SIZE), 
                1.0f, new SpriteEffects(), 0);

            foreach (Site building in entries)
            {
                building.draw(spBatch);
            }

            if (npcs != null)
            {
                foreach (NPC npc in npcs)
                    npc.draw(spBatch, textures);
            }
        }

        private void check_keys(KeyboardState kstate)
        {
            float old_location_X = player_location.X;
            float old_location_Y = player_location.Y;

            if (kstate.IsKeyDown(Keys.Down))
            {
                player_location.Y += 4;
                player_direction = (float)(0.5 * Math.PI);
            }
            if (kstate.IsKeyDown(Keys.Up))
            {
                player_location.Y -= 4;
                player_direction = (float)(1.5 * Math.PI);
            }
            if (map.collision(player_location, Area_TextureManager.HALF_CHARACTER_SIZE))
                player_location.Y = old_location_Y;
            if (kstate.IsKeyDown(Keys.Right))
            {
                player_location.X += 4;
                if (kstate.IsKeyDown(Keys.Down))
                    player_direction = (float)(0.25 * Math.PI);
                else if (kstate.IsKeyDown(Keys.Up))
                    player_direction = (float)(1.75 * Math.PI);
                else
                    player_direction = 0.0f;
            }
            if (kstate.IsKeyDown(Keys.Left))
            {
                player_location.X -= 4;
                if (kstate.IsKeyDown(Keys.Down))
                    player_direction = (float)(0.75 * Math.PI);
                else if (kstate.IsKeyDown(Keys.Up))
                    player_direction = (float)(1.25 * Math.PI);
                else
                    player_direction = (float)(1.0 * Math.PI);
            }
            if (map.collision(player_location, Area_TextureManager.HALF_CHARACTER_SIZE))
                player_location.X = old_location_X;
        }
    }
}
